using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using UnityEngine;

public class Lesson7 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region   知识点一 Socket套接字的作用
        //它是C#提供给我们用于网络通信的一个类
        //类名：Socket
        //命名空间：System.Net.Sockets

        //Socket套接字是支持TCP/IP网络通信的基本操作单位
        //一个套接字对象包含以下关键信息
        //1.本机的IP地址和端口
        //2.对方的IP地址和端口
        //3.双方通信的协议信息

        //一个对象标表示一个本地或者远程套接字信息
        //它可以被视为一个数据通道
        //这个通道连接与客户端和服务端之间进行 
        //数据的链接和发送均通过这个通道进行

        //一般在制作长连接游戏时 我们会使用Socket套接字作为我们的通信方案
        //我们通过它连接客户端和服务端 通过它在收发消息
        //你可以抽象的把他想象成一根管子,插在客户端和服务端应用程序上 通过这个管道来传递交换信息
        #endregion

        #region 知识点二 Socket套接字的类型
        //Socket套接字有3中不同的类型
        //1.流套接字
        //  主要用于实现TCP通信 提供了面向连接 可靠的 有序的 数据无差错且无重复的数据传输服务
        //2.数据报套接字
        //  主要用于实现UDP通信 提供了无连接的通信服务 数据包的长度不能大于32kb 不提供正确性检查 不保证顺序 可能出现重发 丢失等情况
        //3.原始套接字(不常用 不深入讲)
        //  主要用于实现IP数据包通信 用于直接访问协议的较低层 用于侦听和分析数据包

        //通过Socket的构造函数 我们可以申明不同类型的套接字
        // Socket s = new Socket();
        // AddressFamily.InterNetwork
        //参数一：AddressFamily 网络寻址 枚举类型 决定寻址方案
        //  常用：
        //  1.InterNetwork IPV4
        //  2.InterNetwork6 IPV6

        //参数二：SocketType 套接字类型 枚举类型 决定套接字的类型
        //  常用：
        //  1.Stream 流套接字   一般用于TCP通信
        //  2.Dgram 数据报套接字 一般用于UDP通信
        //  3.Raw 原始套接字     一般用于IP数据包通信

        //参数三：ProtocolType 协议类型 枚举类型 确定套接字的协议
        //  常用：
        //  1.Tcp TCP协议
        //  2.Udp UDP协议
        //  3.Icmp ICMP协议

        //2,3参数的常用搭配
        // 1.InterNetwork Tcp 
        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        // 2.InterNetwork Udp
        Socket s2 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        #endregion

        #region 知识点三 Socket套接字的常用属性
        //1.套接字的连接状态
        if (s.Connected)
        {

        }
        //2.获取套接字的类型
        print(s.SocketType);
        //3.获取套接字的协议
        print(s.ProtocolType);
        //4.获取套接字的寻址方案
        print(s.AddressFamily);
        //5.从网络中准备读取的数据数据量
        print(s.Available);
        //6.获取本机endpoint对象
        // s.LocalEndPoint as IPEndPoint;
        //7.获取对端endpoint对象
        // s.RemoteEndPoint as IPEndPoint;
        #endregion

        #region 知识点四 Socket的常用方法
        //1.主要用于服务端
        // 1-1:绑定IP和端口
        IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);
        s.Bind(ip);
        // 1-2:设置客户端连接的最大数量
        s.Listen(10);
        // 1-3:等待客户端的连入
        s.Accept();

        //2.主要用于客户端
        // 1-1连接远程服务端
        s2.Connect(ip);
        //3.客户端服务端都会用的
        // 1-1:同步发送和接受信息
        
        // 1-2：异步发送和接受信息

        // 1-3：释放连接并关闭Socket 先与Close调用
        s.Shutdown(SocketShutdown.Both);
        // 1-4：关闭连接 释放所有Socket关联资源
        s.Close();
        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
